import os
import subprocess
import sys
from constant import *

GCC = 'g++'

# 头文件编译选项
inc_option = ['-I' + INC_FOLDER]
for dir in os.listdir(INC_FOLDER):
    if dir.endswith('.h') == False:
        inc_option.append('-I' + INC_FOLDER + dir)

# 静态链接库编译选项
lib_option = ['-L', LIB_FOLDER]
for lib_file in os.listdir(LIB_FOLDER):
    if lib_file.endswith('.a'):
        lib_option.append('-l' + lib_file[3:-2])
    elif lib_file.endswith('.lib'):
        lib_option.append('-l' + lib_file[0:-4])

# 编译选项
cpp_flags = inc_option + (['-g', '-D', 'DEBUG'] if sys.argv[1] == 'debug' else ['-O3'])

# .cpp 与 .o 文件
dirs = os.listdir(SRC_FOLDER)
cpp_files = []
obj_files = []
for dir in dirs:
    if dir.endswith('.cpp'):
        cpp_files.append(SRC_FOLDER + dir)
        obj_files.append(OBJ_FOLDER + dir[0:-3] + 'o')
    else:
        sub_files = os.listdir(SRC_FOLDER + dir)
        for file in sub_files:
            cpp_files.append(SRC_FOLDER + dir + '/' + file)
            obj_files.append(OBJ_FOLDER + file[0:-3] + 'o')

# 编译 .o 文件
print('compile cpp files...')
cpp_files_cnt = len(cpp_files)
format_str = '[%{0}d/%{0}d] \033[1;33;40mcompile\033[0m %s %s'.format(len(str(cpp_files_cnt)))
is_link = False
CHAR_LEN = 40
for i in range(cpp_files_cnt):
    if os.path.exists(obj_files[i]) and os.path.getmtime(cpp_files[i]) < os.path.getmtime(obj_files[i]):
        continue
    print(format_str % (i + 1, cpp_files_cnt, cpp_files[i], ' ' * CHAR_LEN))
    complete_len = int((i + 1) / cpp_files_cnt * CHAR_LEN)
    print('[\033[1;32;40m{}\033[0m'.format('#' * complete_len), end='')
    print('{}] {}%\r'.format('-' * (CHAR_LEN - complete_len), int(i + 1) / cpp_files_cnt * 100), end='')
    command = [GCC] + cpp_flags + ['-c', cpp_files[i], '-o', obj_files[i]]
    try:
        subprocess.check_call(command)
    except subprocess.CalledProcessError:
        print('\033[1;31;40mcompile failed\033[0m')
        os._exit(-1)
    is_link = True

# 链接 .o 文件
if os.path.exists(exe_path) == False or is_link:
    print('\nlink object files...')
    try:
        subprocess.check_call(['g++'] + obj_files + lib_option + ['-o', exe_path])
        print('\033[1;32;40mbuild {} success!\033[0m'.format(exe_path))
    except subprocess.CalledProcessError:
        print('\033[1;31;40mlink failed\033[0m')